home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 126-150 / scopedisk145 / bug / bug.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-19  |  19.7 KB  |  693 lines

  1. /*   bug 
  2.  
  3. bacteria life simulation
  4.  
  5. */
  6.  
  7.  
  8. /*include.pre contains the following precompiled includes :
  9.     #include <functions.h>
  10.     #include <stdio.h>
  11.     #include <math.h>
  12.     #include <exec/types.h>
  13.     #include <graphics/gfxbase.h>
  14.     #include <graphics/sprite.h>
  15.     #include <graphics/gels.h>
  16.     #include <intuition/intuition.h>
  17. */
  18. #include <graphics/gfxmacros.h>
  19.  
  20. /* not yet needed for this pgm 
  21. #include <hardware/custom.h>
  22. #include <fcntl.h>
  23. #include <libraries/dos.h>
  24. #include <devices/audio.h>
  25. #include <exec/memory.h>
  26. */
  27.  
  28. #define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr
  29. #define ABS(a) ((a<0)?(-(a)):(a))
  30.  
  31. extern void *GetMsg();
  32. struct Screen *scr;
  33. struct Window *win, *pwin, *rwin, *gwin;
  34. struct RastPort *rp, *prp, *rrp, *grp;
  35. struct ViewPort *vp;
  36. struct GfxBase *GfxBase;
  37. struct IntuitionBase *IntuitionBase;
  38. struct IntuiMessage *msg;
  39. struct NewScreen sspecs = { 0,0,320,200, 3, 0, 1, NULL ,CUSTOMSCREEN, NULL, NULL, NULL, NULL };
  40.  
  41. UBYTE GadgetSIBuff11[20] = { "ffffffrfffffflffff?" };
  42. struct StringInfo GadgetSInfo11 = {
  43.     GadgetSIBuff11,    NULL, 0, 20, 10, 0,0,0,0,0,0,0,NULL };
  44. struct Gadget gadget11 = {
  45.     NULL,150,22,160,8,    NULL,GADGIMMEDIATE+STRINGRIGHT,STRGADGET,NULL,
  46.     NULL,NULL,NULL,(APTR)&GadgetSInfo11,NULL,NULL };
  47.  
  48. UBYTE GadgetSIBuff10[20] = { "ffffffrffffffrfffff" };
  49. struct StringInfo GadgetSInfo10 = {
  50.     GadgetSIBuff10,    NULL, 0, 20, 10, 0,0,0,0,0,0,0,NULL };
  51. struct Gadget gadget10 = {
  52.     &gadget11,150,34,160,8,    NULL,GADGIMMEDIATE+STRINGRIGHT,STRGADGET,NULL,
  53.     NULL,NULL,NULL,(APTR)&GadgetSInfo10,NULL,NULL };
  54.  
  55. /* 9 is not currently in use */
  56. UBYTE GadgetSIBuff9[16] = { "0" };
  57. struct StringInfo GadgetSInfo9 = {
  58.     GadgetSIBuff9,    NULL, 0, 15, 10, 0,0,0,0,0,0,0,NULL };
  59. struct Gadget gadget9 = {
  60.     NULL,214,116,60,8,    NULL,GADGIMMEDIATE+STRINGRIGHT+LONGINT,STRGADGET,NULL,
  61.     NULL,NULL,NULL,(APTR)&GadgetSInfo9,NULL,NULL };
  62.  
  63. UBYTE GadgetSIBuff8[16] = { "100" };
  64. struct StringInfo GadgetSInfo8 = {
  65.     GadgetSIBuff8,    NULL, 0, 15, 10, 0,0,0,0,0,0,100,NULL };
  66. struct Gadget gadget8 = {
  67.     NULL,214,104,60,8,    NULL,GADGIMMEDIATE+STRINGRIGHT+LONGINT,STRGADGET,NULL,
  68.     NULL,NULL,NULL,(APTR)&GadgetSInfo8,NULL,NULL };
  69.  
  70. UBYTE GadgetSIBuff7[16] = { "10" };
  71. struct StringInfo GadgetSInfo7 = {
  72.     GadgetSIBuff7,    NULL, 0, 15, 10, 0,0,0,0,0,0,10,NULL };
  73. struct Gadget gadget7 = {
  74.     &gadget8,214,92,60,8,    NULL,GADGIMMEDIATE+STRINGRIGHT+LONGINT,STRGADGET,NULL,
  75.     NULL,NULL,NULL,(APTR)&GadgetSInfo7,NULL,NULL };
  76.  
  77. UBYTE GadgetSIBuff6[16] = { "1200" };
  78. struct StringInfo GadgetSInfo6 = {
  79.     GadgetSIBuff6,    NULL, 0, 15, 10, 0,0,0,0,0,0,1200,NULL };
  80. struct Gadget gadget6 = {
  81.     &gadget7,214,80,60,8,    NULL,GADGIMMEDIATE+STRINGRIGHT+LONGINT,STRGADGET,NULL,
  82.     NULL,NULL,NULL,(APTR)&GadgetSInfo6,NULL,NULL };
  83.  
  84. UBYTE GadgetSIBuff5[16] = { "2000" };
  85. struct StringInfo GadgetSInfo5 = {
  86.     GadgetSIBuff5,    NULL, 0, 15, 10, 0,0,0,0,0,0,2000,NULL };
  87. struct Gadget gadget5 = {
  88.     &gadget6,214,68,60,8,    NULL,GADGIMMEDIATE+STRINGRIGHT+LONGINT,STRGADGET,NULL,
  89.     NULL,NULL,NULL,(APTR)&GadgetSInfo5,NULL,NULL };
  90.  
  91. UBYTE GadgetSIBuff4[16] = { "5" };
  92. struct StringInfo GadgetSInfo4 = {
  93.     GadgetSIBuff4,    NULL, 0, 15, 10, 0,0,0,0,0,0,5,NULL };
  94. struct Gadget gadget4 = {
  95.     &gadget5,214,56,60,8,    NULL,GADGIMMEDIATE+STRINGRIGHT+LONGINT,STRGADGET,NULL,
  96.     NULL,NULL,NULL,(APTR)&GadgetSInfo4,NULL,NULL };
  97.  
  98. UBYTE GadgetSIBuff3[16] = { "99" };
  99. struct StringInfo GadgetSInfo3 = {
  100.     GadgetSIBuff3,    NULL, 0, 15, 10, 0,0,0,0,0,0,99,NULL };
  101. struct Gadget gadget3 = {
  102.     &gadget4,214,44,60,8,    NULL,GADGIMMEDIATE+STRINGRIGHT+LONGINT,STRGADGET,NULL,
  103.     NULL,NULL,NULL,(APTR)&GadgetSInfo3,NULL,NULL };
  104.  
  105. UBYTE GadgetSIBuff2[16] = { "50" };
  106. struct StringInfo GadgetSInfo2 = {
  107.     GadgetSIBuff2,    NULL, 0, 15, 10, 0,0,0,0,0,0,50,NULL };
  108. struct Gadget gadget2 = {
  109.     &gadget3,214,32,60,8,    NULL,GADGIMMEDIATE+STRINGRIGHT+LONGINT,STRGADGET,NULL,
  110.     NULL,NULL,NULL,(APTR)&GadgetSInfo2,NULL,NULL };
  111.  
  112. UBYTE GadgetSIBuff1[16] = { "300" };
  113. struct StringInfo GadgetSInfo1 = {
  114.     GadgetSIBuff1,    NULL, 0, 15, 10, 0,0,0,0,0,0,300,NULL };
  115. struct Gadget gadget1 = {
  116.     &gadget2,214,20,60,8,    NULL,GADGIMMEDIATE+STRINGRIGHT+LONGINT,STRGADGET,NULL,
  117.     NULL,NULL,NULL,(APTR)&GadgetSInfo1,NULL,NULL };
  118.  
  119. struct NewWindow wspecs = { 0,0,320,200,0,1,
  120.                 MOUSEBUTTONS | VANILLAKEY | MENUPICK,
  121.                 SMART_REFRESH | ACTIVATE,
  122.                 NULL, NULL, (UBYTE *)"BUG WINDOW",
  123.                 NULL, NULL, 0,0,0,0,CUSTOMSCREEN };
  124. struct NewWindow pwspecs = { 0,0,320,200,0,1,
  125.                 CLOSEWINDOW,
  126.                 SIMPLE_REFRESH | ACTIVATE | WINDOWCLOSE,
  127.                 &gadget1, NULL, (UBYTE *)"PARAMETER WINDOW",
  128.                 NULL, NULL, 0,0,0,0,CUSTOMSCREEN };
  129. struct NewWindow gwspecs = { 0,0,320,200,0,1,
  130.                 CLOSEWINDOW,
  131.                 SIMPLE_REFRESH | ACTIVATE | WINDOWCLOSE,
  132.                 &gadget10, NULL, (UBYTE *)"GENE WINDOW",
  133.                 NULL, NULL, 0,0,0,0,CUSTOMSCREEN };
  134. struct NewWindow rwspecs = { 0,0,320,200,0,1,
  135.                 CLOSEWINDOW,
  136.                 SIMPLE_REFRESH | ACTIVATE | WINDOWCLOSE,
  137.                 NULL, NULL, (UBYTE *)"REPORT WINDOW",
  138.                 NULL, NULL, 0,0,0,0,CUSTOMSCREEN };
  139.  
  140. struct IntuiText M0text[7] = {
  141.     {0, 0, JAM1, 10, 2, NULL,(UBYTE *)"GENES",   NULL},
  142.     {0, 0, JAM1, 10, 2, NULL,(UBYTE *)"PARAMS",  NULL},
  143.     {0, 0, JAM1, 10, 2, NULL,(UBYTE *)"GO",        NULL},
  144.     {0, 0, JAM1, 10, 2, NULL,(UBYTE *)"CONTINUE",NULL},
  145.     {0, 0, JAM1, 10, 2, NULL,(UBYTE *)"REPORT",  NULL},
  146.     {0, 0, JAM1, 10, 2, NULL,(UBYTE *)"TRAILS",  NULL},
  147.     {0, 0, JAM1, 10, 2, NULL,(UBYTE *)"QUIT",    NULL}
  148. };
  149. struct MenuItem Menu0[7] = {
  150.      {&Menu0[1], 0,  0, 76, 12, ITEMTEXT |
  151.          ITEMENABLED | HIGHCOMP, 0, &M0text[0],NULL,0,NULL, 0 },
  152.      {&Menu0[2], 0, 12, 76, 12, ITEMTEXT |
  153.          ITEMENABLED | HIGHCOMP, 0, &M0text[1],NULL,0,NULL, 0 },
  154.     {&Menu0[3], 0, 24, 76, 12, ITEMTEXT |
  155.          ITEMENABLED | HIGHCOMP, 0, &M0text[2],NULL,0,NULL, 0 },
  156.     {&Menu0[4], 0, 36, 76, 12, ITEMTEXT |
  157.          ITEMENABLED | HIGHCOMP, 0, &M0text[3],NULL,0,NULL, 0 },
  158.     {&Menu0[5], 0, 48, 76, 12, ITEMTEXT |
  159.          ITEMENABLED | HIGHCOMP, 0, &M0text[4],NULL,0,NULL, 0 },
  160.     {&Menu0[6], 0, 60, 76, 12, ITEMTEXT |
  161.          ITEMENABLED | HIGHCOMP | CHECKIT, 0, &M0text[5],NULL,0,NULL, 0 },    
  162.     {NULL,      0, 72, 76, 12, ITEMTEXT |
  163.          ITEMENABLED | HIGHCOMP, 0, &M0text[6],NULL,0,NULL, 0 },    
  164. };
  165. struct Menu proj_menu = { NULL,  1, 0, 77, 10, 
  166.             MENUENABLED, "PROJECT",          &Menu0[0]  };
  167.  
  168. #define MAXBUGS 1200
  169. #define MAXAGE  250
  170. #define BEGIN     0
  171. #define CONTIN  1
  172.  
  173. struct abug {
  174.     int    x,y;        /* screen coordinates */
  175.     int    color;        /* color */
  176.     int    type;        /* 0, 1 */
  177.     short  dir;        /* direction of movement */
  178.     short  nrg;        /* food supply */
  179.     short  idx;        /* current index in movement pattern */
  180.     short  age;          /* age */
  181. } bug[MAXBUGS];
  182.  
  183. char *mov[2];  /* movement patterns */
  184. int len[2];
  185.  
  186. int foodval = 1, births[2], starved[2], oldage[2], maxage=MAXAGE;
  187. int initnrg = 200, foodrate = 4,    initfood = 1000, cycles = 2000;
  188. int startbugs = 50, alive[2] = {50,50}, lastbug = 50;
  189. int divnrg = 200, eaten[2] = 0, flags = 0;
  190. int udrawpen = 5;    /* for eraseing or leaving a trail */
  191. int trails = FALSE;
  192.  
  193. /**************************************************************************/
  194. main(argc,argv)
  195. int argc;
  196. char *argv[];
  197. {
  198.     long class;
  199.     short code;
  200.  
  201.     init();
  202.     if( argc > 1) foodval = atoi(argv[1]);
  203.  
  204.     while(1) {
  205.         while( (msg = GetMsg( win->UserPort)) != NULL) ReplyMsg(msg);
  206.         WaitPort(win->UserPort);
  207.         msg = (struct IntuiMessage *)GetMsg( win->UserPort );
  208.         class = msg->Class;
  209.         code = msg->Code;
  210.         ReplyMsg(msg);
  211.         switch( class ) {
  212.             case CLOSEWINDOW :     quit();
  213.             case VANILLAKEY  :    switch( code ) {
  214.                                 case 'g' :
  215.                                 case 'G' : go(BEGIN);    break;
  216.                                 case 'c' : 
  217.                                 case 'C' : go(CONTIN); break;
  218.                                 case 'q' :
  219.                                 case 'Q' : quit();
  220.                                 }
  221.                                 break;
  222.             case MENUPICK    :    switch( MENUNUM(code) ) {
  223.                                 case 0 : switch( ITEMNUM(code) ) {
  224.                                             case 0 : setgenes();
  225.                                                     break;
  226.                                             case 1 : setparms();
  227.                                                     break;
  228.                                             case 2 : go(BEGIN);
  229.                                                     break;
  230.                                             case 3 : go(CONTIN);
  231.                                                     break;
  232.                                             case 4 : report();
  233.                                                     break;
  234.                                             case 5 : if( trails == TRUE){
  235.                                                         Menu0[5].Flags &= ~CHECKED;
  236.                                                         trails = FALSE;
  237.                                                     }    
  238.                                                     else {
  239.                                                         Menu0[5].Flags |= CHECKED;
  240.                                                         trails = TRUE;
  241.                                                     }
  242.                                                     break;
  243.                                              case 6 : quit();
  244.                                         }
  245.                                         break;
  246.                                 case 1 : break;
  247.  
  248.                             }
  249.         }
  250.     }
  251. }
  252.  
  253. init()
  254. {
  255.     int seed;
  256.     char *OpenLibrary();
  257.     static USHORT colormap[20] = {
  258.         0x0000,0x0ddf,0x0ff0,0x0f0f,    /* 0,1 menus and gadgets 2,3 bugs */
  259.         0x0234,0x0922,0x0000,0x0ff0,  /* 4 food 5 trails  6,7 menus & gad  */
  260.  
  261.         0x0f55,0x055f,0x05f5,0x0030,  /* unused in 3 plane screen   */
  262.         0x00ff,0x00f0,0x0000,0x0ff0,    /* */
  263.  
  264.         0x0000,0x0f00,0x0666,0x0700   /* pointer colors */
  265.     };
  266.  
  267.     GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",1);
  268.     IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",1);
  269.  
  270.     scr = OpenScreen( &sspecs );    wspecs.Screen = scr;
  271.     win = OpenWindow( &wspecs );    rp  = win->RPort;
  272.  
  273.     vp  = (struct ViewPort *)ViewPortAddress(win);
  274.     LoadRGB4(vp, &colormap, 20);
  275.     SetMenuStrip(win, &proj_menu);
  276.     srand( (seed = VBeamPos()) );
  277. }
  278.  
  279. quit()
  280. {
  281.     if( win ) CloseWindow(win);
  282.     if( scr ) CloseScreen(scr);
  283.     if( GfxBase ) CloseLibrary( GfxBase );
  284.     if( IntuitionBase) CloseLibrary( IntuitionBase );
  285.     exit(0);
  286. }
  287.  
  288. /* directions nsew = 0123 */
  289.  
  290. go(mode)
  291. int mode;
  292. {
  293.     long class;
  294.     short code;
  295.     int col,tx, ty, i, winner, loser;
  296.     char c, buf[20];
  297.     static int cy = 0;
  298.     register int b;
  299.  
  300.     ClearMenuStrip(win);
  301.     if(trails) udrawpen = 5;
  302.     else udrawpen = 0;
  303.  
  304.     if( mode == BEGIN ) {
  305.         lastbug = 2*startbugs;    /* lastbug is last used structure index */
  306.         alive[0] = startbugs;
  307.         alive[1] = startbugs;
  308.         births[0] = starved[0] = oldage[0] = eaten[0] = 0;
  309.         births[1] = starved[1] = oldage[1] = eaten[1] = 0;
  310.         initbugs();
  311.         cy = 0;
  312.     }
  313.     SetAPen(rp,0);    SetBPen(rp,1);    Move(rp,200,7);    Text(rp,"CYCLES:   ",7);     
  314.     for( ; cy<cycles; cy++) {
  315.         if(cy%10==0) {
  316.             sprintf(buf,"%ld  ",cy);    SetAPen(rp,0);
  317.             Move(rp,264,7);    Text(rp,buf,strlen(buf));
  318.         }
  319.         if( (msg = (struct IntuiMessage *)GetMsg( win->UserPort)) != NULL){
  320.             class = msg->Class;
  321.             code = msg->Code;
  322.             ReplyMsg(msg);
  323.             break;
  324.         }
  325.         if( (alive[0]+alive[1]) <= 0 ) break;
  326.         newfood();
  327.         for(b=0; b<lastbug; b++ ) {
  328.             if( bug[b].nrg == -86 ) continue; /* he is dead */
  329.             --bug[b].nrg;    ++bug[b].age;
  330.             if( bug[b].nrg <= 0 || bug[b].age > maxage) {
  331.                 rip(b);    continue;
  332.             }
  333.             if( bug[b].nrg > divnrg ) mitosis(b);
  334.             switch( (c=*(mov[bug[b].type]+ bug[b].idx)) ) {
  335.                 case 'l' : bug[b].dir = (--bug[b].dir & 3); break;
  336.                 case 'r' : bug[b].dir = (++bug[b].dir & 3); break;
  337.                 case '?' : bug[b].dir = rand() & 3; break;
  338.                 case 'f' : switch( bug[b].dir ) {        /* test location */
  339.                             case 0 :    tx = bug[b].x;    ty = bug[b].y-1;
  340.                                     col = ReadPixel(rp,tx,ty);
  341.                                     break;
  342.                             case 1 :    tx = bug[b].x+1; ty = bug[b].y;
  343.                                     col = ReadPixel(rp,tx,ty);
  344.                                     break;
  345.                             case 2 :    tx = bug[b].x;    ty = bug[b].y+1;
  346.                                     col = ReadPixel(rp,tx,ty);
  347.                                     break;
  348.                             case 3 :    tx = bug[b].x-1; ty = bug[b].y;
  349.                                     col = ReadPixel(rp,tx,ty);
  350.                                     break;
  351.                           }
  352.                          switch(col) {
  353.                              case 4 :  /* eat food */
  354.                                     SetAPen(rp,0);
  355.                                     WritePixel(rp,tx,ty);
  356.                                     bug[b].nrg += foodval;
  357.                                     break;
  358.                              case 2 :
  359.                             case 3:  /* if alien - fight */
  360.                                     if( col != bug[b].color) {
  361.                                         for(i=0;i<lastbug;++i) { /* find opponent */
  362.                                             if(bug[i].x==tx && bug[i].y==ty) {
  363.                                                 winner = (bug[i].nrg>bug[b].nrg)?i:b;
  364.                                                 loser = (winner==i)?b:i;
  365.                                                 continue;
  366.                                             }
  367.                                         }
  368.                                         SetAPen(rp,0);
  369.                                         WritePixel(rp,bug[b].x,bug[b].y);
  370.                                         bug[winner].x = tx;
  371.                                         bug[winner].y = ty;
  372.                                         bug[loser].nrg = -86;
  373.                                         bug[winner].nrg += bug[loser].nrg;
  374.                                         SetAPen(rp,bug[winner].color);
  375.                                         WritePixel(rp,tx,ty);
  376.                                         --alive[bug[loser].type];
  377.                                         ++eaten[bug[loser].type];
  378.                                     }
  379.                                     else {    /*same species  */
  380.                                          bug[b].dir = rand()%4; /*turn random */
  381.                                      }
  382.                                     break;
  383.                             case 1 :  /* hit a wall */
  384.                                     bug[b].dir = rand()%4; /*turn random */
  385.                                     break;
  386.                             case 0 :
  387.                              default:  /* not occupied, move */
  388.                                      SetAPen(rp,udrawpen);
  389.                                       WritePixel(rp,bug[b].x,bug[b].y);
  390.                                     bug[b].x = tx;
  391.                                     bug[b].y = ty;
  392.                                     SetAPen(rp,bug[b].color);
  393.                                     WritePixel(rp,bug[b].x,bug[b].y);
  394.                                     break;
  395.                         }
  396.             }    
  397.             if( ++bug[b].idx > len[bug[b].type]) bug[b].idx = 0;
  398.         }
  399.         WaitTOF();
  400.     }
  401.     SetMenuStrip(win, &proj_menu);
  402. }
  403.  
  404. initbugs()
  405. {
  406.     int i, j, col, typ;
  407.     char *buf;
  408.  
  409.     mov[0] = GadgetSIBuff10;
  410.     mov[1] = GadgetSIBuff11;
  411.     len[0] = strlen(GadgetSIBuff10);
  412.     len[1] = strlen(GadgetSIBuff11);
  413.  
  414.     col = 2;    typ = 0;
  415.     for(j=0; j<2; j++) {
  416.         for( i=j*startbugs; i<startbugs+(j*startbugs); ++i) {
  417.             bug[i].x = rand()%316+2;
  418.             bug[i].y = rand()%188+10;
  419.             bug[i].dir = rand()%4;
  420.             bug[i].nrg = initnrg;
  421.             bug[i].idx = rand()%len[typ];
  422.             bug[i].age = rand()%maxage;
  423.             bug[i].type = typ;
  424.             bug[i].color = col;
  425.         }
  426.         col = 3; typ = 1;
  427.     }
  428.  
  429.     SetAPen(rp,0);
  430.     RectFill(rp,2,10,318,198);
  431.     SetAPen(rp,4);         /* set out food */
  432.     for( i=0; i<initfood; ++i) WritePixel(rp,rand()%316+2,rand()%188+10);
  433. }    
  434.  
  435. newfood()
  436. {
  437.     int i, x, y, c;
  438.  
  439.     for(i=0; i<foodrate; ++i) {
  440.         do {
  441.             x = rand()%316 + 2;
  442.             y = rand()%188 + 10;
  443.             c = ReadPixel(rp,x,y);
  444.         } while( c != 0 );           /* while not color 0 */
  445.         SetAPen(rp,4);
  446.         WritePixel(rp,x,y);
  447.     }
  448. }
  449.  
  450. report()
  451. {
  452.     int i, avg[2], cnt[2], sum[2];
  453.     char buf[81];
  454.  
  455.     rwspecs.Screen = scr;
  456.     rwin = OpenWindow(&rwspecs);
  457.     rrp = rwin->RPort;
  458.  
  459.     cnt[0]=sum[0]=0;
  460.     cnt[1]=sum[1]=0;
  461.     for(i=0; i<lastbug; i++) {
  462.         if( bug[i].nrg > 0 ) {
  463.             ++cnt[bug[i].type];
  464.             sum[bug[i].type] += bug[i].nrg;
  465.         }
  466.     }
  467.  
  468.     avg[0] = (cnt[0]>0) ? sum[0]/cnt[0] : 0;
  469.     avg[1] = (cnt[1]>0) ? sum[1]/cnt[1] : 0;
  470.  
  471.     SetAPen(rrp,2);
  472.     sprintf(buf,"Initial number                 %4ld",startbugs);
  473.      Move(rrp,10,20);    Text(rrp,buf,strlen(buf));
  474.     sprintf(buf,"Births                         %4ld",births[0]);
  475.      Move(rrp,10,30);    Text(rrp,buf,strlen(buf));
  476.     sprintf(buf,"                 Total         %4ld",births[0]+startbugs);
  477.      Move(rrp,10,40);    Text(rrp,buf,strlen(buf));
  478.  
  479.     sprintf(buf,"Starved                        %4ld",starved[0]);
  480.      Move(rrp,10,60);    Text(rrp,buf,strlen(buf));
  481.     sprintf(buf,"Died of old age                %4ld",oldage[0]);
  482.         Move(rrp,10,70);    Text(rrp,buf,strlen(buf));
  483.     sprintf(buf,"Eaten                          %4ld",eaten[0]);
  484.         Move(rrp,10,80);    Text(rrp,buf,strlen(buf));
  485.     sprintf(buf,"                 Total         %4ld",starved[0] + oldage[0] + eaten[0]);
  486.      Move(rrp,10,90);    Text(rrp,buf,strlen(buf));
  487.  
  488.     sprintf(buf,"Currently alive                %4ld",alive[0]);
  489.      Move(rrp,10,110);    Text(rrp,buf,strlen(buf));
  490.     sprintf(buf,"Avgerage energy                %4ld",avg[0]);
  491.      Move(rrp,10,120);    Text(rrp,buf,strlen(buf));
  492.  
  493.  
  494.     SetAPen(rrp,3);
  495.     sprintf(buf,"%4ld",startbugs);
  496.      Move(rrp,208,20);    Text(rrp,buf,strlen(buf));
  497.     sprintf(buf,"%4ld",births[1]);
  498.      Move(rrp,208,30);    Text(rrp,buf,strlen(buf));
  499.     sprintf(buf,"%4ld",births[1]+startbugs);
  500.      Move(rrp,208,40);    Text(rrp,buf,strlen(buf));
  501.  
  502.     sprintf(buf,"%4ld",starved[1]);
  503.      Move(rrp,208,60);    Text(rrp,buf,strlen(buf));
  504.     sprintf(buf,"%4ld",oldage[1]);
  505.         Move(rrp,208,70);    Text(rrp,buf,strlen(buf));
  506.     sprintf(buf,"%4ld",eaten[1]);
  507.         Move(rrp,208,80);    Text(rrp,buf,strlen(buf));
  508.     sprintf(buf,"%4ld",starved[1] + oldage[1] + eaten[1]);
  509.      Move(rrp,208,90);    Text(rrp,buf,strlen(buf));
  510.  
  511.     sprintf(buf,"%4ld",alive[1]);
  512.      Move(rrp,208,110);    Text(rrp,buf,strlen(buf));
  513.     sprintf(buf,"%4ld",avg[1]);
  514.      Move(rrp,208,120);    Text(rrp,buf,strlen(buf));
  515.  
  516.  
  517.     WaitPort(rwin->UserPort);
  518.     msg = (struct IntuiMessage *)GetMsg(rwin->UserPort );
  519.     ReplyMsg(msg);
  520.     CloseWindow(rwin);
  521. }
  522.  
  523. mitosis(n)
  524. int n;
  525. {
  526.     int c, x, y, xo, yo, new, i, j;
  527.  
  528.     if( (alive[0]+alive[1]) >= MAXBUGS-1) return();    /* return if allocated space used */
  529.     for(yo=-1; yo<2; ++yo) {           /* find a spot to have baby */
  530.         for(xo=-1; xo<2; ++xo) {
  531.             c = ReadPixel(rp, bug[n].x+xo, bug[n].y+yo);
  532.             if( c == 0 ) {
  533.                 x = bug[n].x + xo;
  534.                 y = bug[n].y + yo;
  535.                 goto divide;        /* found it */
  536.             }
  537.         }
  538.     }
  539.     return();    /* no space was found */
  540.  
  541.   divide:
  542.     /* look for empty structure left by a dead bug */
  543.     for(i=0, new = -1; i<lastbug; ++i) {
  544.         if( bug[i].nrg == -86 ){
  545.              new = i;        break;
  546.         }
  547.     }
  548.     ++alive[bug[n].type];
  549.     if( new == -1 ) {        /* if no empty spots make a new one */
  550.         new = ++lastbug-1;
  551.     }
  552.     bug[new].x = x;        
  553.     bug[new].y = y;
  554.     bug[new].dir = rand()%4;
  555.     bug[new].nrg = bug[n].nrg/2;
  556.     bug[new].idx = rand()%len[bug[n].type];        
  557.     bug[new].age = 0;         
  558.     bug[n].nrg /= 2;
  559.     bug[new].type = bug[n].type;
  560.     bug[new].color = bug[n].color;
  561.     ++births[bug[n].type];
  562. }
  563.  
  564. setparms()
  565. {
  566.     int i, j;
  567.     long class;
  568.     short code;
  569.     char buf[16];
  570.     static char title[8][24] = {
  571.         {  "Age at death (10-1000)"    },
  572.         {  "Food value (0-1000)"      },
  573.         {  "Initial energy(10-1000)"  },
  574.         {  "Food rate (0-100)"        },
  575.         {  "Cycles (0-100000)"        },
  576.         {  "Initial food (0-10000)"   },
  577.         {  "Initial # bugs(1-500)"   },
  578.         {  "Mitosis nrg(10-10000)"    },
  579.     };
  580.  
  581.     pwspecs.Screen = scr;
  582.     pwin = OpenWindow( &pwspecs );    prp  = pwin->RPort;
  583.  
  584.     /* gadget borders */
  585.     for(i=0; i<8; ++i) {
  586.         j = 12*i;
  587.         SetAPen(prp,3);     RectFill(prp,210,18+j,270,29+j);
  588.         SetAPen(prp,0);     RectFill(prp,212,19+j,268,28+j);
  589.         SetAPen(prp,1);
  590.         Move(prp,20,26+j);    Text(prp,title[i],strlen(title[i]));
  591.     }
  592.  
  593.     RefreshGadgets(&gadget1,pwin,NULL);
  594.  
  595.     while( (msg = GetMsg( pwin->UserPort)) != NULL) ReplyMsg(msg);
  596.     WaitPort(pwin->UserPort);
  597.     msg = (struct IntuiMessage *)GetMsg( pwin->UserPort );
  598.     class = msg->Class;
  599.     code = msg->Code;
  600.     ReplyMsg(msg);
  601.     maxage    = GadgetSInfo1.LongInt;
  602.     foodval   = GadgetSInfo2.LongInt;
  603.     initnrg   = GadgetSInfo3.LongInt;
  604.      foodrate  = GadgetSInfo4.LongInt;
  605.     cycles    = GadgetSInfo5.LongInt;
  606.     initfood  = GadgetSInfo6.LongInt;
  607.     startbugs = GadgetSInfo7.LongInt;
  608.     divnrg    = GadgetSInfo8.LongInt;
  609.  
  610.     if( maxage < 10) GadgetSInfo1.LongInt = maxage = 10;
  611.     if( maxage > 1000) GadgetSInfo1.LongInt = maxage = 1000; 
  612.     if( foodval < 0 ) GadgetSInfo2.LongInt = foodval = 0;
  613.     if( foodval > 1000) GadgetSInfo2.LongInt = foodval = 1000; 
  614.     if( initnrg < 10 ) GadgetSInfo3.LongInt = initnrg = 10;
  615.     if( initnrg > 1000 ) GadgetSInfo3.LongInt = initnrg = 1000;
  616.     if( foodrate < 0 ) GadgetSInfo4.LongInt = foodrate = 0;
  617.     if( foodrate > 100 ) GadgetSInfo4.LongInt = foodrate = 100;
  618.     if( cycles > 100000 ) GadgetSInfo5.LongInt = cycles = 100000;
  619.     if( cycles < 1 ) cycles = 2000000000; 
  620.     if( initfood < 0 ) GadgetSInfo6.LongInt = initfood = 0;
  621.     if( initfood > 10000 ) GadgetSInfo6.LongInt = initfood = 10000;
  622.     if( startbugs < 1 ) GadgetSInfo7.LongInt = startbugs = 1;
  623.     if( startbugs > 500 ) GadgetSInfo7.LongInt = startbugs = 500;
  624.     if( divnrg < 10 ) GadgetSInfo8.LongInt = divnrg = 10;    
  625.     if( divnrg > 10000 ) GadgetSInfo8.LongInt = divnrg = 10000;    
  626.  
  627.     sprintf(buf,"%ld",maxage);
  628.     strcpy(GadgetSIBuff1,buf);
  629.     sprintf(buf,"%ld",foodval);
  630.     strcpy(GadgetSIBuff2,buf);
  631.     sprintf(buf,"%ld",initnrg);
  632.     strcpy(GadgetSIBuff3,buf);
  633.     sprintf(buf,"%ld",foodrate);
  634.     strcpy(GadgetSIBuff4,buf);
  635.     sprintf(buf,"%ld",initfood);
  636.     strcpy(GadgetSIBuff6,buf);
  637.     sprintf(buf,"%ld",startbugs);
  638.     strcpy(GadgetSIBuff7,buf);
  639.     sprintf(buf,"%ld",divnrg);
  640.     strcpy(GadgetSIBuff8,buf);
  641.  
  642.     CloseWindow(pwin);
  643. }
  644.  
  645. rip(b)
  646. int b;
  647. {
  648.     if( bug[b].age > maxage ) ++oldage[bug[b].type];
  649.     else ++starved[bug[b].type];
  650.     --alive[bug[b].type];
  651.  
  652.     SetAPen(rp,4);                    /* change it to food */
  653.     WritePixel(rp,bug[b].x,bug[b].y);
  654.     bug[b].nrg = -86;                 /* signifying he dead */
  655.     WaitTOF();
  656. }
  657.  
  658.  
  659. setgenes()
  660. {
  661.     int i, j;
  662.     long class;
  663.     short code;
  664.     static char title[2][19] = {
  665.         {  "Type 1"    },
  666.         {  "Type 2"     }
  667.     };
  668.  
  669.     gwspecs.Screen = scr;
  670.     gwin = OpenWindow( &gwspecs );    grp  = gwin->RPort;
  671.  
  672.     /* gadget borders */
  673.     for(i=0; i<2; ++i) {
  674.         j = 12*i;
  675.         SetAPen(grp,3);     RectFill(grp,106,20+j,317,31+j);
  676.         SetAPen(grp,0);     RectFill(grp,108,21+j,315,30+j);
  677.         SetAPen(grp,3-i);
  678.         Move(grp,30,28+j);    Text(grp,title[i],strlen(title[i]));
  679.     }
  680.     RefreshGadgets(&gadget10,gwin,NULL);
  681.  
  682.     while( (msg = GetMsg( gwin->UserPort)) != NULL) ReplyMsg(msg);
  683.     WaitPort(gwin->UserPort);
  684.     msg = (struct IntuiMessage *)GetMsg( gwin->UserPort );
  685.     class = msg->Class;
  686.     code = msg->Code;
  687.     ReplyMsg(msg);
  688.     CloseWindow(gwin);
  689. }
  690.  
  691.  
  692.  
  693.